<?php

namespace app\company\controller;

use app\admin\model\department\Lists;
use app\admin\model\month\Salary;
use app\admin\model\product\Listo;
use app\admin\model\Signs;
use app\admin\model\user\Sign;
use app\common\controller\CompanyApi;
use app\common\controller\RedisCluster;
use think\Db;

/**
 * 首页接口
 */
class Usersign extends CompanyApi
{
    protected $noNeedLogin = ['checkSign', 'signing1'];
    protected $noNeedRight = ['*'];


    public function checkSign()
    {
        $week = date('w', time());
        if ($week == '0') {
            $this->success('今日不需要打卡', false);
        }

        $no_sign_days = config('site.no_sign_days');
        if ($no_sign_days) {
            $no_sign_days_arr = explode(' - ', $no_sign_days);
            if (time() >= strtotime($no_sign_days_arr[0]) && time() < strtotime($no_sign_days_arr[1])) {
                $this->success('今日不需要打卡', false);
            }
        }

        $this->success('今日需要打卡', true);
    }

    /**
     * 获取打卡时间
     */
    public function signTimes()
    {
        $userId = $this->auth->id;
        $data = sign_config($userId);
        $this->success('每日打卡时间', $data);
    }

    /**
     * 当前是否打卡
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function isSign()
    {
        $userId = $this->auth->id;
        $data = sign_config($userId);
        $now = time();
        $status = -1;
        foreach ($data as $val) {
            $begin = strtotime($val[0]);
            $end = strtotime($val[1]);
            if ($now < $begin || $now >= $end) {
                continue;
            }
            $where = [
                'createtime' => [['>=', $begin], ['<', $end]],
                'user_id' => $userId,
            ];
            $sinfo = Sign::where($where)->find();
            if (!$sinfo) {
                $status = 0;
            } else {
                $status = 1;
            }
            break;
        }

        $this->success('打卡状态及时间', ['status' => $status]);
    }

    /**
     * 打卡地
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getDistance()
    {
        $lat = input('lat');
        $lng = input('lng');
        if (!$lat || !$lng) {
            $this->error('参数缺失！');
        }

        $userId = $this->auth->id;
        $user = \app\admin\model\department\User::find($userId);
        $linfo = Lists::find($user->department_id);
        $latitude = $linfo->latitude;
        $longitude = $linfo->longitude;
        if (!$latitude || !$longitude) {
            $this->error('该员工尚未设置打卡地址！');
        }
        $distance = get_distance($lat, $lng, $latitude, $longitude);
        $distancec = config('site.distance');
        if ($distance > $distancec) {
            $this->error('超出范围，不可打卡！', $distance);
        }

        $this->success('可以打卡', $distance);
    }

    /**
     * 老版打卡
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function signingo()
    {
        $image = $this->request->post('image');
        if (!$image) {
            $this->error('必须上传打卡照片！');
        }
//        $week = date('w', time());
//        if ($week == '0') {
//            $this->error('今日不需要打卡');
//        }

        $now = time();
        $no_sign_days = config('site.no_sign_days');
        if ($no_sign_days) {
            $no_sign_days_arr = explode(' - ', $no_sign_days);
            if ($now >= strtotime($no_sign_days_arr[0]) && $now < strtotime($no_sign_days_arr[1])) {
                $this->error('今日不需要打卡');
            }
        }

        $userId = $this->auth->id;
        $user = \app\admin\model\department\User::find($userId);
        $data = sign_config($userId);
        $status = -1;
        $is_late = 0;
        $time = 20 * 60;
        $num = 0;
        foreach ($data as $val) {
            $begin = strtotime($val[0]);
            $end = strtotime($val[1]);
            $num += 1;
            if ($now < $begin || $now >= $end) {
                continue;
            }
            $where = [
                'createtime' => [['>=', $begin], ['<', $end]],
                'user_id' => $userId,
            ];
            $sinfo = Sign::where($where)->find();
            if ($sinfo) {
                $this->error('当前时间已打卡！');
            }

            if ($now >= ($end - $time) && in_array($num, [1, 3])) {
                $is_late = 1;
            }
            $status = 0;
            break;
        }

//        $status = 0;
        if ($status == -1) {
            $this->error('未到打卡时间！');
        }

        if ($status == 0) {

            Db::startTrans();
            try {

                // 超过7天未打卡激励收益归零
                if ($user->is_year_bonus == 1 && $user->is_unfreeze_year_bonus == 0) {
                    $lastSignTime = Sign::where('user_id', $userId)->order('id desc')->value('createtime');
                    if ($lastSignTime) {
                        $times = 6 * 24 * 60 * 60;
                        if ($now - $lastSignTime >= $times) {
                            $user->has_year_bonus = 0;
                            $user->save();
                        }
                    }
                }

                $sdata = [
                    'user_id' => $userId,
                    'createtime' => $now,
                    'image' => $image,
                    'is_late' => $is_late,
                ];

                Sign::create($sdata);

                $today = strtotime('today');
                $num = Sign::where('user_id', $userId)->where('createtime', '>', $today)->count();

                if (in_array($num, [2, 4])) {
                    // 添加激励收益（冻结中才可以）
                    if ($user->is_year_bonus == 1 && $user->is_unfreeze_year_bonus == 0) {
                        $half_year_bonus = config('site.half_year_bonus');
                        $total_year_bonus = config('site.total_year_bonus');
                        $user->has_year_bonus += $half_year_bonus;
                        if ($user->has_year_bonus >= $total_year_bonus) {
                            $user->has_year_bonus = $total_year_bonus;
                            $user->is_unfreeze_year_bonus = 1;
                        }
                        $user->save();
                    }

                    if ($user->type == 1) {
                        // 员工增加月薪
                        $salary = round($user->day_salary / 2, 2);
                        $month = strtotime(date('Y-m', $now));
                        $where = [
                            'user_id' => $userId,
                            'datetime' => $month,
                        ];

                        $row = Salary::where($where)->find();
                        if ($row) {
                            $row->salary += $salary;
                            $row->save();
                        } else {
                            $where['salary'] = $salary;
                            $ret = Salary::create($where);
                        }

                    }
                }

                // 提交事务
                Db::commit();
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                $this->error($e->getMessage());
            }

            $this->success('打卡成功！');
        }

        $this->error('非法操作！');
    }

    /**
     * 打卡
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function signingoo()
    {
        $image = $this->request->post('image');
        if (!$image) {
            $this->error('必须上传打卡照片！');
        }
//        $week = date('w', time());
//        if ($week == '0') {
//            $this->error('今日不需要打卡');
//        }

        $now = time();
        $no_sign_days = config('site.no_sign_days');
        if ($no_sign_days) {
            $no_sign_days_arr = explode(' - ', $no_sign_days);
            if ($now >= strtotime($no_sign_days_arr[0]) && $now < strtotime($no_sign_days_arr[1])) {
                $this->error('今日不需要打卡');
            }
        }

        $userId = $this->auth->id;
        $data = sign_config($userId);
        $status = -1;
        $is_late = 0;
        $time = 20 * 60;
        $num = 0;
        foreach ($data as $val) {
            $begin = strtotime($val[0]);
            $end = strtotime($val[1]);
            $num += 1;
            if ($now < $begin || $now >= $end) {
                continue;
            }
            $where = [
                'createtime' => [['>=', $begin], ['<', $end]],
                'user_id' => $userId,
            ];
            $sinfo = Sign::where($where)->find();
            if ($sinfo) {
                $this->error('当前时间已打卡！');
            }

            if ($now >= ($end - $time) && in_array($num, [1, 3])) {
                $is_late = 1;
            }
            $status = 0;
            break;
        }

//        $status = 0;
        if ($status == -1) {
            $this->error('未到打卡时间！');
        }

//        $redis = new RedisCluster();
//        $skey = 'user_sign_sets';
//        $res1 = $redis->sismember($skey, $userId);
//        if ($res1) {
//            $this->error('打卡申请已提交，请耐心等待！');
//        }
//        $lkey = 'user_sign_lists';
//        $value = $userId . '_' . $now . '_' . $is_late . '_' . $image;
//        $res = $redis->lpush($lkey, $value);
//        if ($res) {
//            $redis->sadd($skey, $userId);
//        }
//
////        $this->handleSign();
//        $this->success('打卡申请成功，请耐心等待！');

        $sdata = [
            'user_id' => $userId,
            'createtime' => $now,
            'image' => $image,
            'is_late' => $is_late,
        ];

        Sign::create($sdata);
        $this->success('打卡成功！');
    }

//    public function handleSign()
//    {
//        $redis = new RedisCluster();
//        $lkey = 'user_sign_lists';
//        $len = $redis->llen($lkey);
//        if ($len <= 0) {
//            return;
//        }
//        $sinfo = $redis->rpop($lkey);
////        $len = $redis->llen($lkey);
////        var_dump($len);
//        if (!$sinfo) {
//            return;
//        }
//        $sarr = explode('_', $sinfo);
//        $userId = $sarr[0];
//        $now = $sarr[1];
//        $is_late = $sarr[2];
//        $image = $sarr[3];
//
//        $user = \app\admin\model\department\User::find($userId);
//        Db::startTrans();
//        try {
//
//            // 超过7天未打卡激励收益归零
//            if ($user->is_year_bonus == 1 && $user->is_unfreeze_year_bonus == 0) {
//                $lastSignTime = Sign::where('user_id', $userId)->order('id desc')->value('createtime');
//                if ($lastSignTime) {
//                    $times = 6 * 24 * 60 * 60;
//                    if ($now - $lastSignTime >= $times) {
//                        $user->has_year_bonus = 0;
//                        $user->save();
//                    }
//                }
//            }
//
//            $sdata = [
//                'user_id' => $userId,
//                'createtime' => $now,
//                'image' => $image,
//                'is_late' => $is_late,
//            ];
//
//            Sign::create($sdata);
//
//            $today = strtotime('today');
//            $num = Sign::where('user_id', $userId)->where('createtime', '>', $today)->count();
//            if (in_array($num, [2, 4])) {
//                // 添加激励收益（冻结中才可以）
//                if ($user->is_year_bonus == 1 && $user->is_unfreeze_year_bonus == 0) {
//                    $half_year_bonus = config('site.half_year_bonus');
//                    $total_year_bonus = config('site.total_year_bonus');
//                    $user->has_year_bonus += $half_year_bonus;
//                    if ($user->has_year_bonus >= $total_year_bonus) {
//                        $user->has_year_bonus = $total_year_bonus;
//                        $user->is_unfreeze_year_bonus = 1;
//                    }
//                    $user->save();
//                }
//
//                if ($user->type == 1) {
//                    // 员工增加月薪
//                    $salary = round($user->day_salary / 2, 2);
//                    $month = strtotime(date('Y-m', $now));
//                    $where = [
//                        'user_id' => $userId,
//                        'datetime' => $month,
//                    ];
//
//                    $row = Salary::where($where)->find();
//                    if ($row) {
//                        $row->salary += $salary;
//                        $row->save();
//                    } else {
//                        $where['salary'] = $salary;
//                        $ret = Salary::create($where);
//                    }
//
//                }
//            }
//
//            $skey = 'user_sign_sets';
//            $res2 = $redis->sremmember($skey, $userId);
////            var_dump($skey, $res2);
//            // 提交事务
//            Db::commit();
//        } catch (\Exception $e) {
//            // 回滚事务
//            Db::rollback();
//            write_log($e->getMessage(), 'redis_error');
//        }
//    }

    public function signing()
    {
        $image = $this->request->post('image');
        if (!$image) {
            $this->error('必须上传打卡照片！');
        }
//        $week = date('w', time());
//        if ($week == '0') {
//            $this->error('今日不需要打卡');
//        }

        $now = time();
        $no_sign_days = config('site.no_sign_days');
        if ($no_sign_days) {
            $no_sign_days_arr = explode(' - ', $no_sign_days);
            if ($now >= strtotime($no_sign_days_arr[0]) && $now < strtotime($no_sign_days_arr[1])) {
                $this->error('今日不需要打卡');
            }
        }

        $userId = $this->auth->id;
        $data = sign_config($userId);
        $status = -1;
        $is_late = 0;
        $time = 20 * 60;
        $num = 0;
        $start1 = strtotime(date('Y-m-d ' . '13:00'));
        $end1 = strtotime(date('Y-m-d ' . '13:30'));
        if ($now >= $start1 && $now <= $end1) {
            // 并发期
            $data = [$data[2]];
        }
        $redis = new RedisCluster();
        $skey = 'user_sign_sets';
        $value = $userId;
        foreach ($data as $val) {
            $begin = strtotime($val[0]);
            $end = strtotime($val[1]);
            $num += 1;
            if ($now < $begin || $now >= $end) {
                continue;
            }
            $value = $begin . '_' . $end . '_' . $userId;
//            $where = [
//                'createtime' => [['>=', $begin], ['<', $end]],
//                'user_id' => $userId,
//            ];
//            $sinfo = Sign::where($where)->find();
//            if ($sinfo) {
//                $this->error('当前时间已打卡！');
//            }
            if ($redis->sismember($skey, $value)) {
                $this->error('当前时间已打卡！');
            }

            if ($now >= ($end - $time) && in_array($num, [1, 3])) {
                $is_late = 1;
            }
            $status = 0;
            break;
        }

//        $status = 0;
        if ($status == -1) {
            $this->error('未到打卡时间！');
        }

        $sdata = [
            'user_id' => $userId,
            'createtime' => $now,
            'image' => $image,
            'is_late' => $is_late,
        ];

        Sign::create($sdata);
        $redis->sadd($skey, $value);
        $redis->set($value, $now, 86400);
        $this->success('打卡成功！');
    }

    /**
     * 今日打卡记录
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function todaySign()
    {
        $userId = $this->auth->id;
        $data = sign_config($userId);
        $redis = new RedisCluster();
        foreach ($data as &$val) {
            $begin = strtotime($val[0]);
            $end = strtotime($val[1]);
            $signTime = 0;
            $key = $begin . '_' . $end . '_' . $userId;
            $value = $redis->get($key);
            if ($value) {
                $signTime = date('H:i', $value);
            } else {
                $where = [
                    'createtime' => [['>=', $begin], ['<', $end]],
                    'user_id' => $userId,
                ];
                $sinfo = Sign::where($where)->find();
                if ($sinfo) {
                    $signTime = date('H:i', $sinfo->createtime);
                }
            }

            $val['sign_time'] = $signTime;
        }

        $this->success('今日打卡记录', $data);
    }

    /**
     * 打卡统计
     */
    public function signReport()
    {
        $user = $this->auth->getUser();
//        if ($user->is_leader != 1 && $user->is_manager != 1) {
//            $this->error('权限不足！');
//        }
        $start_time = $this->request->post('start_time');
        $end_time = $this->request->post('end_time');
        if (!$start_time || !$end_time) {
            $this->error('参数缺失！');
        }

        $start_time = strtotime($start_time);
        $end_time = strtotime($end_time);
        $days = ceil(($end_time - $start_time) / 86400);
        $where = [
            'status' => 'normal',
            'is_leave' => 0
        ];
        if ($user->is_manager != 1 && $user->is_leader != 1) {
            $where['id'] = $user->id;
        }
        if ($user->is_manager != 1 && $user->is_leader == 1) {
            $department_id = $user->department_id;
            $where['department_id'] = $department_id;
        }

        $ids = \app\admin\model\department\User::where($where)->column('id');
        $total1 = count($ids);
        $map = [
            'createtime' => [['>=', $start_time], ['<=', $end_time]]
        ];
        if ($user->is_manager != 1) {
            $map['user_id'] = ['in', $ids];
        }
        $total2 = Sign::where($map)->count();
        $map['is_late'] = 1;
        $total3 = Sign::where($map)->count();

        $rate = 0;
        if ($total1) {
            $rate = ($total2 / ($total1 * 4 * $days)) * 100;
        }
        $rate = round($rate, 1);
        $this->success('打卡统计', ['rate' => $rate, 'total0' => $total1, 'total1' => $total1 * 4 * $days, 'total2' => $total2, 'total3' => $total3]);
    }

    /**
     * 统计详情
     * @throws \think\exception\DbException
     */
    public function signDetail()
    {
        $user = $this->auth->getUser();
//        if ($user->is_leader != 1 && $user->is_manager != 1) {
//            $this->error('权限不足！');
//        }
        $start_time = $this->request->post('start_time');
        $end_time = $this->request->post('end_time');
        $type1 = $this->request->post('type1');
        $type2 = $this->request->post('type2');
        $pageSize = $this->request->post('page_size', 15);
        if (!$start_time || !$end_time) {
            $this->error('参数缺失！');
        }

        $start_time = strtotime($start_time);
        $end_time = strtotime($end_time);
        $where = [
            'status' => 'normal'
        ];
        if ($user->is_manager != 1 && $user->is_leader != 1) {
            $where['id'] = $user->id;
        }
        if ($user->is_manager != 1 && $user->is_leader == 1) {
            $department_id = $user->department_id;
            $where['department_id'] = $department_id;
        }

        $ids = \app\admin\model\department\User::where($where)->column('id');

        if ($type1 == 1) {
            $map = [
                'createtime' => [['>=', $start_time], ['<', $end_time]],
            ];

            if ($user->is_manager != 1) {
                $map['user_id'] = ['in', $ids];
            }

            if ($type2 == 2) {
                $map['is_late'] = 0;
            } elseif ($type2 == 3) {
                $map['is_late'] = 1;
            }
            $lists = Sign::where($map)->paginate($pageSize)->each(function ($item) {
                $info = \app\admin\model\department\User::field('username,nickname,avatar')->find($item['user_id']);
                $item['user'] = $info;
                $item['createtime'] = date('Y-m-d H:i:s', $item['createtime']);
            });
        } elseif ($type1 == 2) {
            $map = [
                'date' => [['>=', $start_time], ['<', $end_time]],
            ];
            $dates = [];
            if ($user->is_manager != 1) {
                $department_id = $user->department_id;
                if ($user->is_leader == 1) {
                    $nids = \app\admin\model\department\User::where('department_id', $department_id)->column('id');
                } else {
                    $nids = [$user->id];
                }

                $map['user_id'] = ['in', $nids];
            }
            $lists = Signs::where($map)->order('id asc')->select();
            foreach ($lists as $key => $val) {
                $user_ids_arr = [];
                $uinfo = \app\admin\model\department\User::where('id', $val->user_id)
                    ->where('is_leave', 0)->find();
                if (!$uinfo) {
                    continue;
                }
                $nicknames = $uinfo->nickname . '(' . $val['num'] . ')';
                $user_ids_arr[] = $nicknames;

                $nuser_ids = implode(',', $user_ids_arr);
                $date = date('Y-m-d', $val->date);
                $dates[] = [
                    'date' => $date,
                    'nuser_ids' => $nuser_ids
                ];
            }
            if ($dates) {
                $ndates = $nndates = []; //想要的结果
                foreach ($dates as $k => $v) {
                    $ndates[$v['date']][] = $v["nuser_ids"];
                }

                foreach ($ndates as $k1 => $v1) {
                    $nndates[] = [
                        'date' => $k1,
                        'nuser_ids' => implode(',', $v1)
                    ];
                }
                $dates = $nndates;
            }
            $lists = $dates;
        }

        $this->success('打卡记录', $lists);
    }
}
